﻿using System;
using System.Diagnostics;
using System.IO;
using System.Security.Principal;
using System.Threading;
using System.Windows;
using Logistics.Configuration;
using Logistics.Utils;
using Logistics.Win;
using Logistics.DataManage.DB;

namespace Logistics
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class MainApp : Application
    {

        /// <summary>
        /// Constructor
        /// </summary>
        public MainApp()
        {
            AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
            String CurrentDirectory = Environment.CurrentDirectory;
            if (CurrentDirectory.StartsWith("C:") && CurrentDirectory.Contains("Program Files"))
                Elevate();
        }

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            LogUtils.WriteDebug("程序启动--MainApp！");

            //Disable shutdown when the dialog closes
            Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;
            //初始化
            LogUtils.WriteDebug("初始化配置文件--MainApp！");
            String m_configXml = GlobalObjects.ConfigFileLocation;
            GlobalSetting GSetting = new GlobalSetting(m_configXml);
            GlobalObjects.GSetting = GSetting;

            //开始产品注册验证
            if (GlobalObjects.RegisterProduct != RegisterProduct.None)
            {
                LogUtils.WriteDebug("进入产品注册--MainApp！");
                bool result = RegisterMgr.SecurityCheckLogin();
                if (!result)
                {
                    //验证失败，退出
                    Environment.Exit(-1);
                }
            }
            //开始CheckMachineID
            bool ret = CheckMachineID();
            if (!ret)
            {
                //检查失败，退出
                Environment.Exit(-1);
            }
            //开始检查数据库文件
            if (!EnsureSQLiteDbFile())
            {
                //检查失败，退出
                Environment.Exit(-1);
            }

            //开始同步服务器端数据
            DataDownloadWin win = new DataDownloadWin();
            win.AutoClose = true;//下载完成自动关闭
            win.ShowDialog();

            //要求用户登录
            IIdentity principal = Thread.CurrentPrincipal.Identity;
            if (!principal.IsAuthenticated)
            {
                LoginWin loginWin = new LoginWin();
                bool? result = loginWin.ShowDialog();
                if (result == null || result.Value == false)
                {
                    //登录失败
                    Environment.Exit(-1);
                }
            }

            //显示主窗口
            //Re-enable normal shutdown mode.
            MainWindow mainWin = new MainWindow();
            Current.ShutdownMode = ShutdownMode.OnMainWindowClose;
            Current.MainWindow = mainWin;
            mainWin.Show();
        }
        private bool CheckMachineID()
        {
            try
            {
                string MachineNum = GlobalObjects.GSetting.MachineID;
                if (string.IsNullOrEmpty(MachineNum))
                {
                    LogUtils.WriteError("全局配置中找不到机器码[MachineNum]--MainApp！");
                    MessageBox.Show("软件基础设置不完整，请与管理者联系！");
                    return false;
                }
            }
            catch (Exception)
            {
                LogUtils.WriteError("全局配置中机器码[MachineNum]检测失败--MainApp！");
                MessageBox.Show("软件基础设置不完整，请与管理者联系！");
                return false;
            }
            return true;
        }

        #region 权限提升
        public void Elevate()
        {
            // 如果不是以administrator身份运行
            if (!IsRunAsAdmin())
            {
                // 以administrator身份，重启自己
                ProcessStartInfo proc = new ProcessStartInfo();
                proc.UseShellExecute = true;
                proc.WorkingDirectory = Environment.CurrentDirectory;
                proc.FileName = Path.Combine(Environment.CurrentDirectory, "Logistics.exe");
                proc.Verb = "runas";
                try
                {
                    Process.Start(proc);
                }
                catch
                {
                    // 如果用户拒绝提升权限，直接退出
                }
                Environment.Exit(-1);   // 退出
            }
        }
        #endregion

        /// <summary>
        /// 检查当前进程是否以administrator身份运行
        /// </summary>
        /// <returns>
        /// </returns>
        private bool IsRunAsAdmin()
        {
            WindowsIdentity id = WindowsIdentity.GetCurrent();
            WindowsPrincipal principal = new WindowsPrincipal(id);
            return principal.IsInRole(WindowsBuiltInRole.Administrator);
        }

        /// <summary>
        /// 检查数据库文件
        /// </summary>
        /// <returns></returns>
        private bool EnsureSQLiteDbFile()
        {
            String SQLiteDbFilePath = ConnectStringMgr.SqliteDbLocation;
            if (String.IsNullOrWhiteSpace(SQLiteDbFilePath))
            {
                MessageBox.Show("请先配置SQLite数据库连接", "配置错误", MessageBoxButton.OK, MessageBoxImage.Error);
                return false;
            }
            if (!File.Exists(SQLiteDbFilePath))
            {
                //数据库文件不存在，从数据库模版拷贝一个
                String DBTemplateFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "App_Data/DBTemplate.db");
                if (!File.Exists(DBTemplateFile))
                {
                    String msg = "无法找到数据库模版文件，请重新安装程序或手动拷贝数据库模版文件到:" + DBTemplateFile;
                    MessageBox.Show(msg, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    return false;
                }
                if (DBTemplateFile == SQLiteDbFilePath)
                {
                    MessageBox.Show("请勿使用数据库模版文件存储数据,请重新配置数据库连接串！", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                    return false;
                }
                File.Copy(DBTemplateFile, SQLiteDbFilePath);
            }
            return true;
        }

        #region 异常处理
        private void Application_DispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
        {
            HandleException(e.Exception);
            e.Handled = true;//如果不加，在捕获异常后程序会退出
        }
        private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            try
            {
                Exception ex = e.ExceptionObject as Exception;
                HandleException(ex);
            }
            catch (Exception ex)
            {
                HandleException(ex);
            }
        }
        private static void HandleException(Exception ex)
        {
            if (ex != null)
            {
                LogUtils.WriteError(ex.ToString());
                MessageBox.Show(ex.ToString());
            }
            else
            {
                LogUtils.WriteLog("exception is null");
            }
        }
        #endregion
    }
}
